package com.shm.singlecamera.Utils;

import android.util.Size;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SizeUtils {

    private static final int MINIMUM_PREVIEW_SIZE = 960;

    public static Size chooseOptimalSize(final Size[] choices, final int width, final int height) {
        Map<Float, Integer> ratios = new HashMap<>();
        Map<Integer, Integer> areas = new HashMap<>();

        // 计算预览窗口高宽比
        float ratio = (float) height / (float) width;

        // 首先选取宽高比与预览窗口高宽比一致且最大的输出尺寸
        for (int i = 0; i < choices.length; ++i) {
            Size choice = choices[i];

            if (choice.getWidth() < MINIMUM_PREVIEW_SIZE ||
                    choice.getHeight() < MINIMUM_PREVIEW_SIZE ){
                continue;
            }

            if (choice.getWidth() < width ||
                    choice.getHeight() < height ){
                continue;
            }

            // 计算高宽比
            float currentRatio = (float) choice.getHeight() / (float) choice.getWidth();
            float diff = Math.abs(currentRatio - ratio);
            ratios.put(diff, i);

            // 计算面积
            int area = choice.getHeight() * choice.getWidth();
            areas.put(area, i);
        }

        // 排序，将高宽比和面积都按照升序排序
        List<Map.Entry<Float, Integer>> ratiosList = new ArrayList<>(ratios.entrySet());
        ratiosList.sort(Map.Entry.comparingByKey());

        List<Map.Entry<Integer, Integer>> areasList = new ArrayList<>(areas.entrySet());
        areasList.sort(Map.Entry.comparingByKey());

        int maxIndex = getMaxIndex(choices, ratiosList, areasList);

        return choices[maxIndex];
    }

    public static Size chooseOptimalSquareSize(final Size[] choices, final int width, final int height) {
        // 用于存储符合条件的长宽相等的候选尺寸
        List<Size> validSquareSizes = new ArrayList<>();

        // 筛选条件：
        // 1. 尺寸满足最小预览要求（>= MINIMUM_PREVIEW_SIZE）
        // 2. 长宽都 >= 目标尺寸（width/height）
        // 3. 长宽相等（正方形）
        for (Size choice : choices) {
            if (choice.getWidth() < MINIMUM_PREVIEW_SIZE || choice.getHeight() < MINIMUM_PREVIEW_SIZE) {
                continue;
            }
            if (choice.getWidth() < width || choice.getHeight() < height) {
                continue;
            }
            if (choice.getWidth() != choice.getHeight()) {
                continue; // 只保留长宽相等的尺寸
            }
            validSquareSizes.add(choice);
        }

        // 如果没有符合条件的尺寸，返回 null 或默认值（根据需求调整）
        if (validSquareSizes.isEmpty()) {
            return null;
        }

        // 按面积从小到大排序，选择最小的正方形
        validSquareSizes.sort((a, b) ->
                (a.getWidth() * a.getHeight()) - (b.getWidth() * b.getHeight())
        );

        return validSquareSizes.get(0);
    }

    private static int getMaxIndex(Size[] choices, List<Map.Entry<Float, Integer>> ratiosList, List<Map.Entry<Integer, Integer>> areasList) {
        List<Integer> scores = new ArrayList<>();

        for(int i = 0; i < choices.length; ++i){
            scores.add(0);
        }

        for(int i = 0; i < ratiosList.size(); ++i){
            int score = ratiosList.size() - i - 1;
            // 给长宽比两倍权重
            scores.set(ratiosList.get(i).getValue(), score + scores.get(ratiosList.get(i).getValue()));
            scores.set(areasList.get(i).getValue(), score + scores.get(areasList.get(i).getValue()));
        }

        // 找到得分最高的位置
        int maxIndex = 0;
        int maxScore = Integer.MIN_VALUE;

        // 计算得分并找到得分最高的位置
        for (int i = 0; i < scores.size(); ++i) {
            int score = scores.get(i);
            if (score > maxScore) {
                maxScore = score;
                maxIndex = i;
            }
        }
        return maxIndex;
    }

}
